如同之前提過的,DynamoDB的索引跟RDBMS的索引不一樣,RDBMS索引是加速查詢效能的用途,但是對key-value資料庫來說,索引是取得資料的手段。我們之前透過主要索引Partition Key&Sort Key進行過資料的存取,本篇則說明GSI使用上的其他基本概念。
索引對DynamoDB來說並非只是增加一組定義屬性為key在資料表上作為參考這麼單純,建立一個索引即是包含一份資料表的投影副本。
有關索引的建立必要參數中屬性projection (投影)
- KEYS_ONLY – 索引中的每個項目僅包含表格分割區索引鍵和排序索引鍵值,加上索引鍵值。KEYS_ONLY 選項將帶來最小的 次要索引。
- INCLUDE – 除了 KEYS_ONLY 中說明的屬性,次要索引 將包含您指定的其他非索引鍵屬性。
- ALL – 次要索引 包含來源表格中的所有屬性。由於所有表格資料皆複製於索引中,ALL 投影將帶來最大的 次要索引。
此參數定義了當你用此GSI進行Query或Scan時,會取得的屬性會有那些。仔細看選項內容你會發現,所有投影最少會包含主要索引的屬性(hash&range attributes),這是因為全域次要索引只能用於取得資料,更新資料必須使用包含Partition Key的索引,也就是主索引與本機次要索引 。
至於如果應用前篇提到的GSI屬性多載設計方法,你應該會用ALL參數以適應不同類型的項目。但如果GSI有專用目的,建議仍要考慮只投影必要屬性,因為資料表中投影屬性數目仍會增加資料寫入成本。
就如同主索引一般,GSI定義描述也可以是僅有Partition Key或是Partition Key&Sort Key。查詢方式也一樣,針對hash attribute取得資料,對於range給予查詢條件等。
掃描雖然之前提過的描述聽起來會花很大量的讀取(收費),但是我們有一種需求就是取得最新幾筆資料、最前幾筆(分數)排序資料時就會用到。尤其是下一個段落提到GSI的佈建模式也會給你合理使用Scan的好處。
有鑑於資料表中必定且需要存的在屬性只有主索引的屬性,其他屬性並非且沒有限制每個Item當中都擁有,即便是定義建立資料表、索引時定義的屬性也一樣。比如說如果建立了一個gsi_1並且定義pk為屬性score,那麼該資料表只有擁有屬性score的item會被gsi_1紀錄並投影,甚至是如果擁有屬性score的item相對來說並不多的話,我們可以稱作此gsi_1為稀疏索引 。
所以相對於主索引、本機次要索引,全域次要索引實際的佈建資源使用視實際的屬性存在數量而定,甚至在DynamoDB的資料操作中你甚至可以為某個項目移除屬性,而讓他移出索引。
所以對於少量存在的屬性資料,卻需要經常頻繁的針對性查詢時,GSI配合Scan仍是個很好用的方式。比如說擁有分數的前幾名資料,或是需要進行作業被設定flag的項目(但是處理完後你應該將flag屬性移除而不是設定為false或其他代表失效的內容)。